package cymbol;

import org.antlr.v4.runtime.tree.ParseTreeProperty;

public class RefPhase extends CymbolBaseListener {
    ParseTreeProperty<Scope> scopes;
    GlobalScope globals;
    Scope currentScope;

    public RefPhase(GlobalScope globals, ParseTreeProperty<Scope> scopes) {
        this.scopes = scopes;
        this.globals = globals;
    }

    public void enterFile(CymbolParser.FileContext context) {
        currentScope = globals;
    }

    public void enterFunctionDecl(CymbolParser.FunctionDeclContext context) {
        currentScope = scopes.get(context);
    }

    public void exitFunctionDecl(CymbolParser.FunctionDeclContext context) {
        currentScope = currentScope.getEnclosingScope();
    }

    public void enterBlock(CymbolParser.BlockContext context) {
        currentScope = scopes.get(context);
    }

    public void exitBlock(CymbolParser.BlockContext context) {
        currentScope = currentScope.getEnclosingScope();
    }

    public void exitVar(CymbolParser.VarContext context) {
        String name = context.ID().getSymbol().getText();
        Symbol var = currentScope.resolve(name);
        if (var == null) {
            CheckSymbols.error(context.ID().getSymbol(), "no such variable: " + name);
        }
        if (var instanceof FunctionSymbol) {
            CheckSymbols.error(context.ID().getSymbol(), name + " is not a variable");
        }
    }

    public void exitCall(CymbolParser.CallContext context) {
        String funcName = context.ID().getText();
        Symbol method = currentScope.resolve(funcName);
        if (method == null) {
            CheckSymbols.error(context.ID().getSymbol(), "no such function: "+funcName);
        }
        if (method instanceof  VariableSymbol) {
            CheckSymbols.error(context.ID().getSymbol(), funcName+" is not a function");
        }

    }
}
